webpack 简介
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
功能进化
- Webpack V1(2014.2.20)
- 编译、打包
- HMR(模块热更新)
- 代码分割
- 文件处理(loader、plugin)
- Webpack V2(2017.1.18)
- Tree Shaking(在项目中没有实际运用的代码会被删除,打包体积更小)
- ES module
- 动态Import
- Webpack V3(2017.6.19)
- Scope Hoisting(作用域提升)
- Magic Comments(配合动态import使用)
- Webpack V4(2018.2.27)
- webpack 4 更快(速度提升98%)!
- Mode, 零配置以及默认值
- 再见 CommonsChunkPlugin
- WebAssembly 支持
- 模块类型简介以及 .mjs 支持
核心概念
Entry 代码的入口,打包入口:
1 | // 一个入口 |
Output 打包输出
1 | { |
Loaders 处理css img 等各种其他文件
1 | // 单个loader |
1 | // 多个loader |
Plugins 插件
1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm |
使用 webpack
webpack 默认打包js,官网
编译打包ES6
需要两个loader:npm i babel-loader babel-core --save-dev
1 | module.exports = { |
{ test: Condition }:匹配特定条件。一般是提供一个正则表达式或正则表达式的数组,但这不是强制的。
{ include: Condition }:匹配特定条件。一般是提供一个字符串或者字符串数组,但这不是强制的。
{ exclude: Condition }:排除特定条件。一般是提供一个字符串或字符串数组,但这不是强制的。
{ and: [Condition] }:必须匹配数组中的所有条件
{ or: [Condition] }:匹配数组中任何一个条件
{ not: [Condition] }:必须排除这个条件
Babel Presets
虽然引入了 babel-loader
,但是它并不知道是根据什么规范来打包的,这个时候就需要配置一个Babel Presets(预设):npm i babel-preset-env --save-dev
1 | module.exports = { |
也可以新建.babelrc文件,上面是直接将presets设置在loader中的,也可以单独写在.babelrc文件中,babel会自动读取,具体请查看babel
Babel Polyfill
安装: npm install --save-dev babel-polyfill
使用 babel-polyfill: import 'babel-polyfill'
Babel 默认只转换新的 JavaScript 语法,而不转换新的 API。例如,Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转译。如果想使用这些新的对象和方法,必须使用 babel-polyfill,为当前环境提供一个垫片。在这里可以说是为了使用某个浏览器或者其他执行环境不支持的函数或者对象能够使用而添加的原型方法,或者第三方库
例如:
我们想要使用 es2015 的语法中的某些新的对象方法或者数据类型,就需要添加 babel-polyfill,例如 Array.from 方法很多浏览器不支持,你就需要垫片来提高兼容性。
为了在版本低浏览器中能够使用 promise,我们需要提前执行一个 promise 文件,以便能够在全局中使用。
babel-runtime
安装: npm i --save-dev babel-runtime
1 | ; |
类似上面的帮助函数 _defineProperty 可能会重复出现在一些模块里,导致编译后的代码体积变大。Babel 为了解决这个问题,提供了单独的包 babel-runtime 供编译模块复用工具函数。
安装: npm i babel-plugin-transform-runtime --save-dev
在.babelrc文件加入配置:
1 | { |
启用插件 babel-plugin-transform-runtime 后,Babel 就会使用 babel-runtime 下的工具函数,转译代码如下:
1 | ; |
除此之外,babel 还为源代码的非实例方法(Object.assign,实例方法是类似这样的 “foobar”.includes(“foo”))和 babel-runtime/helps 下的工具函数自动引用了 polyfill。这样可以避免污染全局命名空间,非常适合于 JavaScript 库和工具包的实现。例如 const obj = {}, Object.assign(obj, { age: 30 });
转译后的代码如下所示:
1 | ; |
打包Typescript
安装 typescript-loader: npm i typescript ts-loader --save-dev
或者第三方loader:npm i typescript awesome-typescript-loader --save-dev
webpack.config.js
1 | module.exports = { |
tsconfig.json
1 | { |
处理CSS
安装 css-loader 和 style-loader // 在页面中插入style标签:
npm i style-loader css-loader --save-dev
webpack.config.js:
1 | module.exports = { |
配置Less/Sass
安装:
npm i less-loader less --save-dev
npm i sass-loader node-sass --save-dev
webpack.config.js
1 | module.exports = { |
提取CSS
安装插件:npm i extract-text-webpack-plugin --save-dev
webpack.config.js:
1 | var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin); |
PostCss
PostCSS是一个使用JS插件转换样式的工具。
与 PostCss 相关联的插件还有: Autoprefixer、CSS-nano、CSS-next等
- Autoprefixer 可以为我们的 CSS 加上各个浏览器的前缀,我们只需要写标准的就好
- CSS-nano 可以压缩我们的 CSS,在 CSS-loader 中内嵌的 CSS 压缩就是采用该方式
- CSS-next 可以让我们现在使用未来的 CSS 新语法
使用这些功能需要安装:
1 | npm install postcss postcss-loader autoprefixer cssnano postcss-cssnext --save-dev |
webpack.config.js
1 | var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); |
文件处理
图片处理
使用场景:
- CSS中引入的图片 —— file-loader
- 自动合成雪碧图 —— postcss-sprites
- 压缩图片 —— img-loader
- Base64编码 —— url-loader
安装:npm i file-loader url-loader img-loader postcss-sprites --save-dev
url-loader(urL-loader 有file-loader的功能,可以只用url-loader):
1 | module: { |
img-loader
1 | module: { |
postcss-sprites 合成雪碧图
1 | module: { |
注: 还可以在 url-loader 的 options 设置 name 来修改合成后图片的名字:
1 | { |
字体文件处理
1 | module: { |
处理第三方js库
1 | new webpack.ProvidePlugin({ //jQuery的JS文件在本地加载之后不能直接使用,需要如下配置 |
或者在 module 中使用 imports-loader :
安装: npm i imports-loader --save-dev
1 | { |
生成html
利用 html-webpack-plugin 插件
1 | var HtmlWebpackPlugin = require('html-webpack-plugin'); |
html内图片处理
配置用 html-withimg-loader
1 | ... |
完~